home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / nos042_s / nettime.c < prev    next >
C/C++ Source or Header  |  1994-11-24  |  12KB  |  411 lines

  1. /****************************************************************************
  2. *    Author        :    G Todd                                                    *
  3. *    Language     :    Borland C++ 3.1                                            *
  4. *    Logfile        :    nettime.c                                                *
  5. *    Project        :    DIS KA9Q.                                                *
  6. *    Date         :    24 Aug 92                                                *
  7. *    Revision     :    1.1        GT    Originate.                                    *
  8. *                :    1.2        MT    "auto", "maxcorrect" and "mincorrect".        *
  9. *    21 Sep 92    :    1.3        MT    Fix correction reports.                        *
  10. *                :            GT    Disable idle timeout while setting the time.*
  11. *    28 Sep 92    :    1.4        GT    Wait for next timer tick after setting the    *
  12. *                :                time.                                        *
  13. *    09 Apr 93    :    1.5        GT    Fix spurious error message from do_set ().    *
  14. *                :                Increase connect timeout.                    *
  15. *                :                Fix smtptick () call.                        *
  16. *    13 Apr 93    :    1.6        GT    Time setting tweaks.                        *
  17. *                :                "time delay" command.                        *
  18. *    08 May 93    :    1.9        GT    Fix warnings.                                *
  19. *****************************************************************************
  20. *    Purpose        :    Routines for setting KA9Q's time from the remote host.    *
  21. *                :    Uses the protocol described in RFC 868.                    *
  22. *****************************************************************************
  23. *                :    Copyright Giles Todd 1992.  All rights reserved.        *
  24. *                :    The right of Giles Todd to be identified as the author    *
  25. *                :    of this work has been asserted by him in accordance        *
  26. *                :    with the Copyrights, Designs and Patents Act, 1988.        *
  27. *                :    No restrictions on the use of this module with KA9Q.    *
  28. *****************************************************************************
  29. $Id: nettime.c 1.9 93/07/16 11:46:57 ROOT_DOS Exp $
  30. *
  31. *    ATARI Version by David Nash - dnash@chaos.demon.co.uk
  32. *
  33. *  __stdargs bg_set, pause->Pause
  34. *  don't swap bytes for little endian order
  35. *
  36. *  24.11.94 DFN - Remove stdargs from do_delay
  37. *
  38. ****************************************************************************/
  39.  
  40. #include    <stdio.h>
  41. #include    <time.h>
  42. #include    "global.h"
  43. #include    "mbuf.h"
  44. #include    "cmdparse.h"
  45. #include    "proc.h"
  46. #include    "socket.h"
  47. #include    "timer.h"
  48. #include    "netuser.h"
  49. #include    "commands.h"
  50. #include    "ip.h"
  51. #include    "smtp.h"
  52. #include    "pppfsm.h"
  53.  
  54. #if    defined (time)
  55. #undef    time                                /* remove macro                    */
  56. #endif
  57.  
  58. extern int ext_dokicks(void);
  59.  
  60. int done_set_time = 0;    /* have we set the time since this open?    */
  61.  
  62. /****************************************************************************
  63. *    Static function declarations.                                            *
  64. ****************************************************************************/
  65.  
  66. static int do_auto __ARGS((int argc, char **argv, void *p));
  67. static int do_delay __ARGS((int argc, char **argv, void *p));
  68. static int do_server __ARGS((int argc, char **argv, void *p));
  69. static int do_maxcorrect __ARGS((int argc, char **argv, void *p));
  70. static int do_mincorrect __ARGS((int argc, char **argv, void *p));
  71. static int do_read __ARGS((int argc, char **argv, void *p));
  72. static int do_set __ARGS((int argc, char **argv, void *p));
  73. static void __stdargs bg_set __ARGS((int s, void *unused, void *p));
  74. static void start_of_connection __ARGS((void));
  75.  
  76. /****************************************************************************
  77. *    Static data.                                                            *
  78. ****************************************************************************/
  79.  
  80. static time_t correction = 0L;                /* difference in seconds         */
  81.                                             /* between remote and PC clock    */
  82. static int32 server = 0L;                    /* time server address            */
  83. static int auto_time_set = 0;                /* set time on PPP open?        */
  84. static struct proc *setting_the_time = NULLPROC;
  85. static int32 delay = 10000L;                /* delay for setting up routes    */
  86. static time_t max_correction = 0;            /* !0 is max correction allowed */
  87. static time_t min_correction = 0;            /* !0 is min correction allowed */
  88. static struct cmds time_cmds[] =
  89.     {
  90.     { "auto",        do_auto,    0,        0,    NULLCHAR },
  91.     { "delay",    do_delay,    0,        0,    NULLCHAR },
  92.     { "maxcorrect",do_maxcorrect,0,    0,    NULLCHAR },
  93.     { "mincorrect",do_mincorrect,0,    0,    NULLCHAR },
  94.     { "read",        do_read,    0,        0,    NULLCHAR },
  95.     { "server",    do_server,    0,        0,    NULLCHAR },
  96.     { "set",        do_set,        0,        0,    NULLCHAR },
  97.     { NULLCHAR }
  98.     };
  99.  
  100.  
  101. /****************************************************************************
  102. *    do_time                                                                    *
  103. *    Time commands driver.                                                    *
  104. ****************************************************************************/
  105.  
  106. int do_time (argc, argv, p)
  107. int argc;
  108. char **argv;
  109. void *p;
  110.     {
  111.     return (subcmd (time_cmds, argc, argv, p));
  112.     }    /* int do_time (argc, argv, p) */
  113.  
  114.  
  115. /****************************************************************************
  116. *    do_server                                                                *
  117. *    Display or set the timer server address.                                *
  118. ****************************************************************************/
  119.  
  120. static int do_server (argc, argv, p)
  121. int argc;
  122. char **argv;
  123. void *p;
  124.     {
  125.     int32 n;                                /* temporary                    */
  126.  
  127.     if (argc < 2)
  128.         {
  129.         tprintf ("%s\n", inet_ntoa (server));
  130.         }
  131.     else if ((n = resolve (argv[1])) == 0)
  132.         {
  133.         tprintf (Badhost, argv[1]);
  134.         return (1);
  135.         }
  136.     else
  137.         server = n;
  138.  
  139.     return (0);
  140.     }    /* static int do_server (argc, argv, p) */
  141.     
  142.  
  143. /****************************************************************************
  144. *    do_read                                                                    *
  145. *    Read the time from the remote and set the correction value.                *
  146. ****************************************************************************/
  147.  
  148. static int do_read (argc, argv, p)
  149. int argc;
  150. char **argv;
  151. void *p;
  152.     {
  153.     struct sockaddr_in fsocket;                /* socket address                */
  154.     int s;                                    /* socket handle                */
  155.     union
  156.         {
  157.         time_t time;
  158.         char bytes[sizeof (time_t)];
  159.         } result;                            /* data from remote                */
  160. #ifndef ATARI
  161.     char t;                                    /* temporary                    */
  162. #endif    
  163.     char *cp;                                /* -> error message                */
  164.     time_t pctime;                            /* PC time                        */
  165.  
  166.     if (server == 0L)
  167.         {
  168.         tprintf (Badhost, "0.0.0.0");
  169.         return (1);
  170.         }
  171.         
  172.     /* Set up the connection. */
  173.  
  174.     fsocket.sin_family = AF_INET;
  175.     fsocket.sin_addr.s_addr = server;
  176.     fsocket.sin_port = IPPORT_TIME;
  177.     s = socket (AF_INET, SOCK_STREAM, 0);
  178.     sockmode (s, SOCK_BINARY);
  179.     alarm (connect_wait_val);                /* set timeout                    */
  180.     if (connect (s, (char *) &fsocket, SOCKSIZE) != 0)
  181.         {
  182.         alarm (0L);
  183.         cp = sockerr (s);
  184.         tprintf ("TIME: %s connect failed: %s\n", psocket (&fsocket),
  185.                  cp != NULLCHAR ? cp : "");
  186.         (void) close_s (s);
  187.         done_set_time = FALSE;
  188.         return (1);
  189.         }
  190.  
  191.     alarm (0L);
  192.  
  193.     /* Try to receive the time. */
  194.  
  195.     if (recv (s, result.bytes, sizeof (result.bytes), 0) !=
  196.         sizeof (result.bytes))
  197.         {
  198.         tprintf ("TIME: receive failed\n");
  199.         close_s (s);
  200.         done_set_time = FALSE;
  201.         return (1);
  202.         }
  203.  
  204.     close_s (s);
  205.  
  206.     /* Calculate the correction value. */
  207.  
  208. #ifndef ATARI    
  209.     t = result.bytes[0];
  210.     result.bytes[0] = result.bytes[3];
  211.     result.bytes[3] = t;
  212.     t = result.bytes[1];
  213.     result.bytes[1] = result.bytes[2];
  214.     result.bytes[2] = t;
  215. #endif
  216.     
  217.     result.time -= 2208988800L;                /* adjust epoch                    */
  218.         
  219.     pctime = time (NULL);
  220.     correction = result.time - pctime;
  221.     tprintf ("TIME: correction = %ld seconds\n", correction);
  222.     pctime = ka9q_time (NULL);
  223.     tprintf ("Time now (GMT): %s", asctime (gmtime (&pctime)));
  224.     return (0);
  225.     }    /* static int do_read (argc, argv, p) */
  226.  
  227.  
  228. /****************************************************************************
  229. *    do_set                                                                    *
  230. *    Set the PC's clock from the time server.                                *
  231. ****************************************************************************/
  232.  
  233. static int do_set (argc, argv, p)
  234. int argc;
  235. char **argv;
  236. void *p;
  237.     {
  238.     time_t n;                                /* temporary                    */
  239.     int correction_abs;
  240.  
  241.     if (correction == 0L)
  242.         {
  243.         /* Set up the correction. */
  244.  
  245.         if (do_read (0, NULL, NULL) != 0)
  246.             return (1);
  247.             
  248.         }
  249.  
  250.     correction_abs = (int) labs(correction);
  251.  
  252.     if (max_correction && correction_abs > max_correction)
  253.         {
  254.         tprintf("TIME: required correction (%ld) greater than maximum (%ld)\n",
  255.             correction, max_correction);
  256.         correction = 0L;
  257.         return (0);
  258.         }
  259.  
  260.     if (min_correction && correction_abs < min_correction)
  261.         {
  262.         tprintf("TIME: required correction (%ld) less than minimum (%ld)\n",
  263.             correction, min_correction);
  264.         correction = 0L;
  265.         return (0);
  266.         }
  267.  
  268.     n = ka9q_time (NULL);                    /* get tweaked time                */
  269.     (void) stime (&n);                        /* and set the PC clock            */
  270.     log(-1,"PC clock adjusted by %ld at %s (server %s)",
  271.                                     correction, ctime(&n), inet_ntoa(server));
  272.     correction = 0L;                        /* no need for a correction now    */
  273.     tprintf ("TIME: PC clock set\n");
  274.     return (0);
  275.     }    /* static int do_set (argc, argv, p) */
  276.  
  277.  
  278.  
  279. /*---------------------------------------------------------------------------
  280.     do_delay - Display or set the timer delay
  281. ---------------------------------------------------------------------------*/
  282.  
  283. static int do_delay(int argc, char *argv[], void *p)
  284. {
  285.     if (argc < 2) {
  286.         tprintf ("auto kick delay: %lu\n", delay / 1000L);
  287.         return 0;
  288.     }
  289.  
  290.     delay = atol (argv[1]) * 1000L;            /* set timeout                    */
  291.  
  292.     return 0;
  293. }
  294.     
  295.  
  296. /****************************************************************************
  297. *    ka9q_time                                                                *
  298. *    Replacement for library "time ()" function.  Called by other modules    *
  299. *    via nasty macro substitution.                                            *
  300. ****************************************************************************/
  301.  
  302. time_t ka9q_time (t)
  303. time_t *t;
  304.     {
  305.     time_t rc;                                /* return value                    */
  306.  
  307.     (void) time (&rc);                        /* get the PC's idea            */
  308.     rc += correction;
  309.     if (t != NULL)
  310.         *t = rc;
  311.  
  312.     return (rc);
  313.     }    /* time_t ka9q_time (t) */
  314.  
  315.     
  316. /****************************************************************************
  317. *    do_auto                                                                    *
  318. *    Should we do a 'time set' every time ppp ipcp opens?                     *
  319. ****************************************************************************/
  320.  
  321. static int do_auto (argc, argv, p)
  322. int argc;
  323. char **argv;
  324. void *p;
  325.     {
  326.     return setbool(&auto_time_set, "TIME SET auto mode", argc, argv);
  327.     }
  328.  
  329. int try_set_time (argc, argv, p)
  330. int argc;
  331. char **argv;
  332. void *p;
  333.     {
  334.     struct ppp_s *ppp_p = p;
  335.     
  336.     done_set_time = 1;
  337.     if (!auto_time_set)
  338.         return 0;
  339.     if (setting_the_time == NULLPROC)
  340.         setting_the_time = newproc("set time", 512, bg_set, 0, NULL, ppp_p, 0);
  341.     return 0;
  342.     }
  343.  
  344. static void start_of_connection()
  345.     {
  346.     int32 zero = 0;
  347.     smtptick((void *) zero);
  348.     ext_dokicks();
  349.     }
  350.  
  351. static void __stdargs bg_set (int s, void *unused, void *p)
  352. {
  353.     int32 save_idle_durn = 0L;
  354.     struct ppp_s *ppp_p = p;
  355.     
  356.     Pause (delay);
  357.  
  358.     if (ppp_p->idle_durn != 0L)
  359.         {
  360.         /* Stop the PPP idle timer. */
  361.  
  362.         stop_timer (&(ppp_p->idle_timer));
  363.         save_idle_durn = ppp_p->idle_durn;
  364.         ppp_p->idle_durn = 0L;
  365.         }
  366.         
  367.     do_set(0, NULL, NULL);
  368.     setting_the_time = NULLPROC;
  369.     if (save_idle_durn != 0L)
  370.         {
  371.         /* Restart the PPP idle timer. */
  372. #ifdef ATARI                                        /* pwait(Tick) hangs routine            */
  373.         pwait(NULL);
  374. #else        
  375.         pwait ((void *)&Tick);                    /* wait for next timer tick            */
  376. #endif        
  377.         ppp_p->idle_durn = save_idle_durn;
  378.         set_timer (&(ppp_p->idle_timer), ppp_p->idle_durn);
  379.         start_timer (&(ppp_p->idle_timer));
  380.         }
  381.     start_of_connection();
  382.     }
  383.  
  384. static int
  385. do_maxcorrect(argc,argv,p)
  386. int argc;
  387. char *argv[];
  388. void *p;
  389. {
  390.     if(argc < 2){
  391.         tprintf("TIME: maximum correction: %d\n", max_correction);
  392.         return 0;
  393.     }
  394.     max_correction = atoi(argv[1]);
  395.     return 0;
  396. }
  397.  
  398. static int
  399. do_mincorrect(argc,argv,p)
  400. int argc;
  401. char *argv[];
  402. void *p;
  403. {
  404.     if(argc < 2){
  405.         tprintf("TIME: minimum correction: %d\n", min_correction);
  406.         return 0;
  407.     }
  408.     min_correction = atoi(argv[1]);
  409.     return 0;
  410. }
  411.